/**
 @Name：视图模块
 @Author：蓝博
 */

layui.define(['laytpl', 'layer', 'element', 'setter'], function (exports) {
    var $ = layui.jquery,
        laytpl = layui.laytpl,
        layer = layui.layer,
        setter = layui.setter,
        //对外接口
        view = function (dom) {
            return new Class(dom);
        },
        //构造器
        Class = function (dom) {
            this.container = (typeof dom === 'string' ? $(dom) : dom);
        };

    //路由处理
    view.router = {
        index: null,
        lash: null,
        routers: {},
        init: function (options) {
            view.router.index = view.router.routerInfo(options.index).path.join('/');
            if (options.pop && typeof options.pop === 'function') {
                view.router.pop = options.pop;
            }
            if (options.notFound && typeof options.notFound === 'function') {
                view.router.notFound = options.notFound;
            }
            Class.prototype.onhashchange();
            window.onhashchange = function () {
                Class.prototype.onhashchange();
            };
            return this;
        },
        /* 注册路由 */
        reg: function (hash, handler) {
            if (hash) {
                if (!handler) {
                    handler = function () { };
                }
                if (hash instanceof Array) {
                    for (var i in hash) {
                        this.reg.apply(this, [hash[i], handler]);
                    }
                } else if (typeof hash === 'string') {
                    hash = view.router.routerInfo(hash).path.join('/');
                    if (typeof handler === 'function') {
                        view.router.routers[hash] = handler;
                    } else if (typeof handler === 'string' && view.router[handler]) {
                        view.router.routers[hash] = view.router.routers[handler];
                    }
                }
            }
            return this;
        },
        /* 获取路由信息 */
        routerInfo: function (url) {
            url || (url = location.hash);
            var hash = url.replace(/^#+/g, '').replace(/\/+/g, '/');
            if (hash.indexOf('/') !== 0) {
                hash = '/' + hash;
            }
            return layui.router('#' + hash);
        },
        /* 刷新路由 */
        refresh: function (url) {
            Class.prototype.onhashchange(url, true);
        },
        /* 跳转路由 */
        go: function (hash) {
            location.hash = '#' + view.router.routerInfo(hash).href;
        }
    };

    //Ajax请求
    view.req = function (options) {
        var success = options.success,
            error = options.error,
            request = setter.request, //自定义请求字段
            response = setter.response, //自定义响应字段
            debug = function () {
                return setter.debug ? '<br><cite>URL：</cite>' + options.url.split('?')[0] : '';
            };
        options.data = options.data || {};
        options.headers = options.headers || {};
        if (request.tokenName) {
            //自动给参数传入默认 token
            options.data.v = layui.cache.version;
            //自动给 Request Headers 传入 token
            options.headers[request.tokenName] = request.tokenName in options.headers ? options.headers[request.tokenName] : (layui.data(setter.tableName)[request.tokenName] || 'not');
        }
        delete options.success;
        delete options.error;
        return $.ajax($.extend({
            type: 'get',
            dataType: 'json',
            success: function (res) {
                if (options.dataType == 'json') {
                    var statusCode = response.statusCode;
                    if (res[response.statusName] == statusCode.ok) {
                        typeof options.done === 'function' && options.done(res);
                    }
                    else {
                        layer.msg('很抱歉，返回数据异常或数据已不存在！', { icon: 2 });
                    }
                }
                typeof success === 'function' && success(res);
            },
            error: function (e) {
                if (options.dataType == 'json') {
                    var errorTest = e.responseText,
                        errorObj = eval("(" + errorTest + ")"),
                        content = ['请求异常，请重试</br><cite>错误状态码：</cite>' + e.status + '，<cite>错误信息：</cite>' + errorObj[response.msgName].split('|')[0], debug()].join('');
                    view.popupTips(content);
                }
                typeof error === 'function' && error(e);
            }
        }, options));
    };

    //显示加载动画
    view.showLoading = function (elem, type, opacity, size) {
        if (elem !== undefined && (typeof elem != 'string') && !(elem instanceof $)) {
            type = elem.type;
            opacity = elem.opacity;
            size = elem.size;
            elem = elem.elem;
        }
        (type === undefined) && (type = 1);
        (size === undefined) && (size = 'sm');
        (elem === undefined) && (elem = 'body');
        var loader = [
            '<div class="ball-loader ' + size + '"><span></span><span></span><span></span><span></span></div>',
            '<div class="rubik-loader ' + size + '"></div>',
            '<div class="signal-loader ' + size + '"><span></span><span></span><span></span><span></span></div>'
        ];
        $(elem).addClass('page-no-scroll');  // 禁用滚动条
        if ($(elem).children('.page-loading').length <= 0) {
            $(elem).append('<div class="page-loading">' + loader[type - 1] + '</div>');
            //$(elem).children('.page-loading') = $(elem).children('.page-loading');
        }
        (opacity !== undefined) && ($(elem).children('.page-loading').css('background-color', 'rgba(255,255,255,' + opacity + ')'));
        $(elem).children('.page-loading').show();
    };

    //移除加载动画
    view.removeLoading = function (elem, fade, del) {
        (elem === undefined) && (elem = 'body');
        (fade === undefined) && (fade = true);
        $(elem).children('.page-loading').remove();
        $(elem).removeClass('page-no-scroll');
    };

    //刷新url方式的layer
    view.reloadLayer = function (index, url, success) {
        var layero;
        if (url) {
            if (typeof index === 'number') {
                layero = $('#layui-layer' + index);
            } else {
                layero = $(index);
            }
            layero.data('url', url);
            view(layero.children('.layui-layer-content')).render(url).done(function () {
                success && success(layero[0], index);
            });
        }
    };

    //弹窗
    view.popup = function (options) {
        var success = options.success,
            end = options.end,
            skin = options.skin;
        delete options.success;
        delete options.end;
        delete options.skin;
        return layer.open($.extend({
            type: 1,
            offset: '70px',
            shade: .1,
            fixed: false,
            resize: false,
            skin: 'layui-layer-admin' + (skin ? ' ' + skin : ''),
            end: function (e) {
                layer.closeAll('tips');
                typeof end === 'function' && end(e);
            },
            success: function (layero, index) {
                view.reloadLayer(index, options.url, success);
            }
        }, options))
    };

    //提示弹窗
    view.popupTips = function (content, options) {
        return view.popup($.extend({
            content: content,
            maxWidth: 300,
            offset: '20px',
            anim: 6,
            id: 'LAY_popupTips'
        }, options))
    };

    //右侧弹窗
    view.popupRight = function (options) {
        return view.popup($.extend({
            id: 'LAY_popupRight',
            anim: -1,
            offset: 'r',
            move: false,
            fixed: true,
            area: '336px',
            title: false,
            closeBtn: false,
            shadeClose: true,
            skin: 'layui-anim layui-anim-rl layui-layer-adminRight'
        }, options));
    };

    //关闭当前iframe层弹窗
    view.closeThisDialog = function () {
        parent.layer.close(parent.layer.getFrameIndex(window.name));
    };

    //关闭非iframe类型的弹窗
    view.closeDialog = function (elem) {
        var id = $(elem).parents('.layui-layer').attr('id').substring(11);
        layer.close(id);
    };

    //让当前的ifram弹层自适应高度
    view.iframeAuto = function () {
        parent.layer.iframeAuto(parent.layer.getFrameIndex(window.name));
    };

    //绑定表单弹窗
    view.modelForm = function (layero, btnFilter, formFilter) {
        $(layero).addClass('layui-form');
        (formFilter) && ($(layero).attr('lay-filter', formFilter));
        // 确定按钮绑定submit
        $(layero).find('.layui-layer-btn .layui-layer-btn0').attr('lay-submit', '').attr('lay-filter', btnFilter);
    };

    //获取弹窗数据
    view.getLayerData = function (index, key) {
        if (index === undefined) {
            index = parent.layer.getFrameIndex(window.name);
            (index !== undefined) && (index = parseInt(index));
            return parent.layui.view.getLayerData(index, key);
        } else if (isNaN(index)) {
            var layId = $(index).parents('.layui-layer').attr('id');
            layId && (index = layId.substring(11));
        }
        var layerData = admin.layerData['d' + index];
        if (key) {
            return layerData ? layerData[key] : undefined;
        }
        return layerData;
    };

    //放入弹窗数据
    view.putLayerData = function (index, key, value) {
        if (index === undefined) {
            index = parent.layer.getFrameIndex(window.name);
            (index !== undefined) && (index = parseInt(index));
            return parent.layui.view.putLayerData(key, value, index);
        } else if (isNaN(index)) {
            index = $(index).parents('.layui-layer').attr('id').substring(11);
        }
        var layerData = admin.getLayerData(index);
        layerData || (layerData = {});
        layerData[key] = value;
        admin.layerData['d' + index] = layerData;
    };

    //请求模板文件渲染
    Class.prototype.render = function (views) {
        var that = this;
        //请求模板
        view.req({
            url: (setter.base + layui.cache.viewPath + views + setter.viewSuffix).replace("//", "/"),
            dataType: 'html',
            success: function (res) {
                res = ('<section>' + res + '</section>');
                if (that.then) {
                    that.then(res);
                    delete that.then;
                }
                that.parse(res);
                if (that.done) {
                    that.done(res);
                    delete that.done;
                }
            },
            error: function (xhr, error, obj) {
                if (xhr.status == 404) {
                    that.render('shared/error', {}, xhr.status);
                }
                if (that.error) {
                    that.error({
                        xhr: xhr,
                        error: error,
                        obj: obj
                    });
                    delete that.done;
                }
            }
        });
        return that;
    };

    //解析模板
    Class.prototype.parse = function (html) {
        var elem = (typeof html === 'object' ? html : $(html)),
            elemTemp = elem.find('*[template]'),
            fn = function (options) {
                var tpl = laytpl(options.dataElem.html()),
                    res = $.extend({
                        params: router.params
                    }, options.res);
                options.dataElem.after(tpl.render(res));
                try {
                    options.done && new Function('d', options.done)(res);
                } catch (e) {
                    console.error(options.dataElem[0], '\n存在错误回调脚本\n\n', e)
                }
            },
            router = layui.router();
        this.container['html'](elem.children());
        router.params = this.params || {};
        //遍历模板区块
        for (var i = elemTemp.length; i > 0; i--) {
            (function () {
                var dataElem = elemTemp.eq(i - 1),
                    layDone = dataElem.attr('lay-done') || dataElem.attr('lay-then'), //获取回调
                    url = laytpl(dataElem.attr('lay-url') || '').render(router), //接口 url
                    data = laytpl(dataElem.attr('lay-data') || '').render(router), //接口参数
                    headers = laytpl(dataElem.attr('lay-headers') || '').render(router); //接口请求的头信息
                try {
                    data = new Function('return ' + data + ';')();
                } catch (e) {
                    hint.error('lay-data: ' + e.message);
                    data = {};
                };
                try {
                    headers = new Function('return ' + headers + ';')();
                } catch (e) {
                    hint.error('lay-headers: ' + e.message);
                    headers = headers || {}
                };
                if (url) {
                    view.req({
                        type: dataElem.attr('template'),
                        url: url,
                        data: data,
                        dataType: 'json',
                        headers: headers,
                        success: function (res) {
                            fn({
                                dataElem: dataElem,
                                res: res,
                                done: layDone
                            });
                        }
                    });
                } else {
                    fn({
                        dataElem: dataElem,
                        done: layDone
                    });
                }
            }());
        }
        return this;
    };

    //直接渲染字符
    Class.prototype.send = function (views, data) {
        var tpl = laytpl(views || this.container.html()).render(data || {});
        this.container.html(tpl);
        return this;
    };

    //视图请求成功后的回调
    Class.prototype.then = function (callback) {
        this.then = callback;
        return this;
    };

    //视图渲染完毕后的回调
    Class.prototype.done = function (callback) {
        this.done = callback;
        return this;
    };

    //视图发生错误后的回调
    Class.prototype.error = function (callback) {
        this.error = callback;
        return this;
    };

    //路由发生变化时执行
    Class.prototype.onhashchange = function (url, refresh) {
        var that = this;
        var routerInfo = view.router.routerInfo(url);
        view.router.lash = routerInfo.href;
        var hash = routerInfo.path.join('/');
        if (!hash || hash === '/') {
            hash = view.router.index;
            routerInfo = view.router.routerInfo(view.router.index);
        }
        view.router.pop && view.router.pop.call(that, routerInfo);
        if (view.router.routers[hash]) {
            routerInfo.refresh = refresh;
            view.router.routers[hash].call(that, routerInfo);
        } else if (view.router.notFound) {
            view.router.notFound.call(that, routerInfo);
        }
        return that;
    };

    //对外输出接口
    exports('view', view);
});